"""
Model Sprockets Module

This is sort of like the central nervous system of dbsprockets.  Views and
Sessions are collected in separate caches and served up as sprockets.
The cache objects may be solidified at some point with a parent class.
They work for right now.


Classes:
Name           Description
Sprockets      A cache of Sprockets
Sprocket       A binding of Session and View configs
Views          A cache of Views
Sessions       A cache of Sessions

Exceptions:
SessionConfigError
ViewConfigError

Functions:
None

Copywrite (c) 2007 Christopher Perkins
Original Version by Christopher Perkins 2007
Released under MIT license.
"""
import types

from dbsprockets.sprockets import Sprockets, ConfigCache, Sprocket

from providerselector import SAORMSelector

from formbase import FormBase, AddRecordForm, EditableForm
from tablebase import TableBase
from entitiesbase import EntitiesBase, EntityDefBase

from fillerbase import ModelsFiller, ModelDefFiller, EditFormFiller, AddFormFiller, FormFiller, TableFiller

class ViewCache(ConfigCache):

    default_configs = { 'model_view'   : EntitiesBase,
                        'edit'         : EditableForm,
                        'add'          : AddRecordForm,
                        'listing'      : TableBase,
                        'metadata'     : EntityDefBase,
                        }

    def __init__(self, session, metadata=None):
        self.session = session
        self.metadata = metadata
        self._provider = SAORMSelector.get_provider(hint=session.bind, metadata=self.metadata)

    def _get(self, key):
        view_type, identifier = self._split_identifiers(key)
        if view_type not in self.default_configs:
            raise ViewConfigError('view_type:%s not found in default bases'%view_type)

        base = self.default_configs[view_type]
        if key != 'model_view':
            base.__entity__   = self._provider.get_entity(identifier)
        base.__provider__ = self._provider
        base.__id__ = key
        return base(self.session)

class FillerCache(ViewCache):
    """Container for SessionConfigs"""

    default_configs = { 'model_view'   : ModelsFiller,
                        'metadata'     : ModelDefFiller,
                        'view'         : FormFiller,
                        'listing'      : TableFiller,
                        'edit'         : EditFormFiller,
                        'add'          : AddFormFiller,
                        }

class ModelSprockets(Sprockets):
    """Set of Associations between widgets and the method to obtain their data"""
    def __init__(self, session, metadata=None):
        self.views    = self.views_type(session, metadata=metadata)
        self.sessions = self.sessions_type(session, metadata=metadata)

    sessions_type = FillerCache
    views_type    = ViewCache

